package drawingBoard;

import drawingBoard.state.Context;
import drawingBoard.action.KeyboardListener;
import drawingBoard.memento.CareTaker;
import drawingBoard.memento.Originator;
import drawingBoard.myFile.MyImageFile;
import drawingBoard.myPanel.ColorPanel;
import drawingBoard.myPanel.MyPanel;
import drawingBoard.myPanel.ToolPanel;
import drawingBoard.tool.AbstractTool;
import drawingBoard.tool.Tool;
import drawingBoard.tool.ToolFactory;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;

import javax.swing.ImageIcon;
import javax.swing.JColorChooser;

import java.awt.*;

import java.awt.event.*;
import java.awt.image.BufferedImage;
import static drawingBoard.tool.Tool.PENCIL_TOOL;

/**
 * ImageFrame是 JFrame的子类
 * 关联 ImageService、MyImage等
 */
public class ImageFrame extends JFrame {
	
	private static ImageFrame instance;

	//定义业务逻辑类
	private ImageService service=new ImageService();
	//初始化屏幕的尺寸
	private Dimension screenSize= MyImageFile.getScreenSize();
	//设置默认画板
	private JPanel drawSpace=createDrawSpace();
	//设置缓冲图片
	private MyImage bufferedImage=new MyImage((int)screenSize.getWidth()/2,(int)screenSize.getHeight()/2,BufferedImage.TYPE_INT_RGB);
	//设置当前使用的工具
	private Tool tool = null;
	//设置画图对象
	Graphics g = bufferedImage.getGraphics();
	//颜色显示面板
	private JPanel currentColorPanel = null;
	//颜色选择器
	private JColorChooser colorChooser = getColorChooser();

	//撤销和恢复(备忘录模式、单例模式)
	public Originator originator = new Originator();
	public CareTaker careTaker = CareTaker.getInstance();
	//设定是否可以撤销(状态模式)
	public Context context = new Context();
	//加给菜单的事件监听器
	ActionListener menuListener = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			service.menuDo(ImageFrame.this, e.getActionCommand());
			if(service.myImage != null){
				my_draw(service.myImage);
			}
		}
	};
	KeyboardListener keyboardListener;  //键盘监听
	private JScrollPane scroll = null;  //默认JScrollPane
	JPanel toolPanel;  //工具栏
	JPanel colorPanel;  //颜色面板
	private ImageFrame() {  //默认构造器
		super();
		init();  //初始化
	}

	//单例模式（懒汉式，线程安全）
	public static synchronized ImageFrame getInstance() {
		if (instance == null) {
			instance = new ImageFrame();
		}
		return instance;
	}

	public void my_draw(BufferedImage image){
		//宽，高
		int height = image.getHeight();
		int width = image.getWidth();
		AbstractTool.drawHeight = height;
		AbstractTool.drawWidth = width;
		//创建一个MyImage
		MyImage myImage = new MyImage(width,height,BufferedImage.TYPE_INT_RGB);
		//把读取到的图片画到myImage上面
		myImage.getGraphics().drawImage(image,0,0,width,height,null);
		this.setBufferedImage(myImage);
		//repaint
		this.getDrawSpace().repaint();
		//重新设置viewport
		ImageService.setViewport(this.getScroll(),getDrawSpace(),width,height);
	}

	public ImageService getService() {
		return this.service;
	}

	public void init() {  //初始化ImageFrame
		//创建工具面板
		MyPanel myPanel = new ToolPanel();   //ToolPanel是抽象类MyPanel的子类
		toolPanel = myPanel.create(this);
		//创建颜色面板
		myPanel = new ColorPanel();   //ColorPanel 也是抽象类MyPanel的子类
		colorPanel = myPanel.create(this);

		setTitle("未命名 - 简易绘图板");  //设置标题
		service.initDrawSpace(this);  //初始化画图
		setIconImage(new ImageIcon("img/icon.png").getImage());  //设置图标
		tool = ToolFactory.getToolInstance(this, PENCIL_TOOL);  //设置正在使用的工具——铅笔
		//创建鼠标移动监听器
		MouseMotionListener motionListener = new MouseMotionAdapter() {
			public void mouseDragged(MouseEvent e) {
				tool.mouseDragged(e);  //拖动鼠标
			}
			public void mouseMoved(MouseEvent e) {  //移动鼠标
				tool.mouseMoved(e);
			}
		};
		//创建鼠标监听器
		MouseListener mouseListener = new MouseAdapter() {
			public void mouseReleased(MouseEvent e) {
				tool.mouseReleased(e);  //松开鼠标
			}
			public void mousePressed(MouseEvent e) {
				tool.mousePressed(e);  //按下鼠标
			}
			public void mouseClicked(MouseEvent e) {
				tool.mouseClicked(e);  //单击鼠标
			}
		};
		//创建键盘监听器
		keyboardListener = new KeyboardListener();
		
		drawSpace.add(keyboardListener);  //陈正刚  this--->drawSpace
		drawSpace.addKeyListener(keyboardListener);
		drawSpace.setVisible(true);

		drawSpace.addMouseMotionListener(motionListener);
		drawSpace.addMouseListener(mouseListener);

		currentColorPanel = ((ColorPanel) myPanel).getCurrentColorPanel();
		createMenuBar();
		//以drawSpace为viewport去创建一个JScrollPane
		scroll = new JScrollPane(drawSpace);
		//设置viewport
		ImageService.setViewport(scroll, drawSpace, bufferedImage.getWidth(),bufferedImage.getHeight());
		//将panel加到本Frame上面
		this.add(scroll, BorderLayout.CENTER);
		this.add(toolPanel, BorderLayout.WEST);
		this.add(colorPanel, BorderLayout.SOUTH);
		//备忘录模式第一个赋值
		g.setColor(Color.WHITE);
		g.drawLine(1, 1, 10, 10);
		AbstractTool.takeEffect(ImageFrame.this);
		originator.setState(getBufferedImage());
		careTaker.add(originator.saveStateToMemento());
		AbstractTool.takeEffect(ImageFrame.this);
		originator.setState(getBufferedImage());
		careTaker.add(originator.saveStateToMemento());
	}

	public JPanel getDrawSpace() {  //获取画布
		return this.drawSpace;
	}

	public JScrollPane getScroll() {  //获取JScroolPane
		return this.scroll;
	}

	public JPanel getToolPanel() {  //获取工具栏
		return this.toolPanel;
	}

	public JPanel getColorPanel() {  //获取颜色面板
		return this.colorPanel;
	}

	public MyImage getBufferedImage() {  //获取图片
		return this.bufferedImage;
	}

	public void setBufferedImage(MyImage bufferedImage) {  //设置图片
		this.bufferedImage = bufferedImage;
	}

	public void setTool(Tool tool) {  //设置工具
		this.tool = tool;
	}

	public Tool getTool() {  //获取工具
		return this.tool;
	}

	public JColorChooser getColorChooser() {  //获取颜色选择器
		if (colorChooser == null) {
			colorChooser = new JColorChooser();
		}
		return colorChooser;
	}

	public JPanel getCurrentColorPanel() {  //获取颜色显示面板
		return this.currentColorPanel;
	}

	public Dimension getScreenSize() {  //获取screenSize
		return this.screenSize;
	}

	public void createMenuBar() {  
		JMenuBar menuBar = new JMenuBar();  //创建菜单栏
		String[] menuArr={"文件","编辑","查看","颜色","帮助"};
		String[][] menuItemArr = {{"新建","打开","保存","-","退出"},{"撤销","恢复"},{"工具箱","颜料盒"},{"编辑颜色"},{"帮助主题","关于"}};
		for (int i = 0; i < menuArr.length; i++) {
			JMenu menu = new JMenu(menuArr[i]);  //创建菜单项
			for (int j = 0; j < menuItemArr[i].length; j++) {
				if (menuItemArr[i][j].equals("-")) {
					menu.addSeparator();  //增加菜单项分隔
				} else {
					JMenuItem menuItem = new JMenuItem(menuItemArr[i][j]);  //新建菜单项
					menuItem.addActionListener(menuListener);
					menu.add(menuItem);  //添加菜单项至菜单
				}
			}
			menuBar.add(menu);  //添加菜单至菜单栏
		}
		//设置JMenubar
		this.setJMenuBar(menuBar);
	}

	//创建画板
	public JPanel createDrawSpace() {
		JPanel drawSpace = new DrawSpace();
		//设置drawSpace的大小
		drawSpace.setPreferredSize(new Dimension((int) screenSize.getWidth(),(int) screenSize.getHeight() - 150));
		return drawSpace;
	}

	//画图区域
	public class DrawSpace extends JPanel {
		//重写void paint(Graphics g)方法
		public void paint(Graphics g) {
			//单击工具后无法使用快捷键Ctrl+Z撤销（陈正刚）
			requestFocus(true);
			
			//draw
			service.repaint(g, bufferedImage);
		}
	}
}
